/* CsJni - .NET / Java Bridge
 * 
 * Copyright 2010 Robert E. Burke Licensed under the Apache License, Version 
 * 2.0 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
 * law or agreed to in writing, software distributed under the License is 
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
*/

// See http://svn.codehaus.org/groovy/trunk/groovy/modules/native_launcher/source/jvmstarter.c
// http://developer.apple.com/mac/library/samplecode/simpleJavaLauncher/Listings/simple_c.html#//apple_ref/doc/uid/DTS10000688-simple_c-DontLinkElementID_5
// http://developer.apple.com/mac/library/technotes/tn2005/tn2147.html#TNTAG32

// (Detect Darwin)
// http://www.koders.com/csharp/fid63F101DAACDB1442377AB51DCA436ECD47ECCBEB.aspx?s=zoom

// (Notes on Mac Platform ID) - http://www.mono-project.com/FAQ:_Technical

// More specific Linux - http://www.novell.com/coolsolutions/feature/11251.html

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace CsJni.PlatformAbstraction
{
    internal class MacPlatform : AbstractUnixPlatform
    {
        public MacPlatform(JavaVMConfiguration cfg)
            : base(cfg)
        {
        }

        public override string PlatformName
        {
            get
            {
                return "Mac";
            }
        }

        public override string GetCreatedJavaVMsMethodName { get { return "JNI_GetCreatedJavaVMs_Impl"; } }
        public override string CreateJavaVMMethodName { get { return "JNI_CreateJavaVM_Impl"; } }

        protected override IntPtr raw_dlopen(string fileName, int mode)
        {
            return NativeMethods.dlopen(fileName, mode);
        }

        protected override IntPtr raw_dlsym(IntPtr hModule, string procName)
        {
            return NativeMethods.dlsym(hModule, procName);
        }

        protected override IntPtr raw_dlerror()
        {
            return NativeMethods.dlerror();
        }

        protected override int raw_dlclose(IntPtr hModule)
        {
            return NativeMethods.dlclose(hModule);
        }

        private sealed class NativeMethods
        {
            private NativeMethods()
            {
            }

            [DllImport("libdl.dylib", BestFitMapping = false, ThrowOnUnmappableChar = true)]
            public static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPStr)] string fileName, int mode);

            [DllImport("libdl.dylib", BestFitMapping = false, ThrowOnUnmappableChar = true)]
            public static extern IntPtr dlsym(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string procName);

            [DllImport("libdl.dylib")]
            public static extern IntPtr dlerror();

            [DllImport("libdl.dylib")]
            public static extern int dlclose(IntPtr hModule);
        }
    }
}
